Alrighty, in this lecture, we're going to set up the local script that's going to be controlling our
guns.
This local script will listen for when our gun is equipped, and then listen for inputs to shoot or
reload the gun.
Since all of the properties for our guns are stored in a separate module.
Scripts.
This local script should work for all of the guns in our game.
So all we need to do is create one local script and then just copy and paste it into each one of our
guns.
So let's get started.
We can create a local script in any one of our guns.
It doesn't matter.
I'll create it in my assault rifle, a new local script.
And inside of our local script, we're going to go ahead and use the same template that we've been using.
I'm going to get rid of this section and this section, and then we can go ahead and create some variables
to refer to our tool so we can get the gun itself, which will just be equal to script dot parent.
We're also going to need to grab the player as well to grab their mouse object.
So we can go ahead and get the player from the player service.
We're also going to need to grab replicated storage, because there's a remote event in there that we're
going to use to communicate with the server when we have shot, or we need to reload our gun.
And the last but not least, to listen for our user input, we're going to use the context action service.
So we'll grab that as well.
And then we can go ahead and refer to our player.
So players local player.
And then we can also get the mouse of our player.
So that's going to be equal to our player.
And there's the function get mouse.
And then we want to go ahead and update a property inside of our mouse.
It's called a target filter and it states determines an object and its descendants to be ignored when
determining mouse dot hit and mouse dot target.
So mouse dot hit and mouse dot target are two properties inside of the mouse that defines what part
the mouse is hovering over, and the position of the mouse in the workspace.
Now we want to ignore any invisible parts in our game.
So we're going to set the target filter equal to the workspace dot filtering folder.
That's why we called it our filtering folder, because we're setting it as the target filter.
And our filtering folder is just filled with a bunch of miscellaneous invisible parts that we don't
want our mouse to interact with when we're calculating the raycast for our gun.
Last but not least, we also want to grab the properties for our gun as well.
That's very important.
So we'll require a gun dot properties.
Now for our gun we want to listen for when our gun is equipped.
And then we also want to listen for when our gun is unequipped.
Now, when our gun is equipped, one of the first things we want to do is we want to update the icon
of our mouse on the screen.
Specifically, we want to set the icon of our mouse to a hit marker so we can set mouse.
The icon and it says the content ID of the image used as the mouse icon.
And I'm going to go ahead and type out the ID of a mouse icon that I found that would work for a gun
system.
So we're going to type out RB asset ID colon and then slash slash, and then the ID for the icon that
I want to use is
11839767092.
So this is going to replace the icon of our mouse with a crosshair.
And then when our gun is equipped the next thing we want to do is we want to listen for input when the
player shoots the gun and when they want to reload the gun.
So we're going to use our context action service and bind an action.
We can call this action our gun shoot.
And then we also want to bind another action for reloading the gun.
So bind action.
We will call this gun reload.
So the function we're going to pass here is going to be passed an action name, an input state as well
as the input object.
Do we want to create a touch button for this?
For shooting?
We're going to do false because the inputs we're going to be listening to is going to be our enum dot
user input type dot mouse button one, as well as the enum dot user input type dot touch.
So we can also support mobile devices.
And then I'm going to copy this and do the exact same thing for our gun reload, but instead the inputs
we want to go ahead and listen to.
Are going to be the enum dot key code dot r, and then we want to create an on screen button for reloading
the gun for mobile players.
Now, since we're going to be able to support whether or not our gun is automatic or semi-automatic,
we want to keep track of when our player is holding down their mouse button or when they have released
their mouse button.
So I'm going to create another variable, and I'm going to call it mouse button down.
And I'm going to set it to false by default.
But if the input state of our mouse button one or our touch if that is equal to the enum dot user input
state of begin, then that means we're beginning to hold down our mouse button so we can set mouse button
down equal to true.
Otherwise, if the input state is equal to the enum dot user input state dot end, then we want to go
ahead and set mouse button down equal to false.
Now for reloading and shooting our gun.
We can go ahead and create a couple of dedicated functions for that.
We can have a function to shoot our gun, and then we can have a function to reload our gun.
And then when we begin to hold down our mouse button or the player begins to touch the screen, then
we want to shoot our gun and we only want to shoot our gun if we have ammo in our magazine.
So in each one of our guns, we actually have an attribute set on them that tells us how much ammo currently
is in the magazine and how much reserve ammo they have, as well as an extra attribute to define whether
or not it is a spread.
So a shotgun, or if it's just a standard gun.
So what we want to do is we want to check if our gun get attribute ammo and mag.
If that's equal to zero, then we don't want to shoot our gun, and instead we want to be able to play
that click sound to tell the player, hey, you don't have any ammo.
So we can go ahead and create that same kind of function we've created before to create a sound instance,
and we'll get past the parent for that sound instance, as well as the sound properties that we'll be
grabbing from our properties module script.
So we'll create a new sound instance dot new sound.
And then we can go ahead and loop through every single property and value in the sound properties.
And then apply that on our sound.
And then afterward, we can set sound parent equal to the parent and then return the sound.
So that way if we don't have any ammo, we can go ahead and create a new sound.
So we'll create a sound, and the parent for that will be the handle of our gun.
And that sound is going to be the properties dot gun click sound properties.
And then we can play this sound when we don't have any ammo.
We'll wait for this sound to complete.
And then we'll just destroy the sound instance and return.
And I'll go ahead and move this after my if statement, because we don't want to set mouse button down
equal to true when we don't have any ammo in our gun.
Now that we confirm that we have enough ammo and we're holding down our mouse button, the next thing
we can check is whether or not this gun is automatic.
If this gun is automatic, then we want to have a while loop running here that will keep shooting our
gun over and over until we either run out of ammo or we lift up our mouse button.
If our gun isn't automatic, then we can simply just call our shoot function, shoot the gun, and then
we also want to be able to wait for a little bit to prevent the player from shooting the gun again based
on the round permanent property of our gun.
So that means we need to calculate the cooldown or the shot cooldown for our gun.
And that's going to be equal to our properties.
Fire rate.
And then there is 60s in a minute.
So we're going to divide 60 by our fire rate to get the cooldown or the time duration between each shot
based on the fire rate.
So that means we can go down and after we shoot our gun we can go ahead and wait for this shot.
Cooldown.
And that means we're going to have to create another boolean to keep track of when we are shooting our
gun, and we'll check if we're already shooting our gun, and then we'll just return.
That way we don't shoot the gun again.
So I'll create a boolean.
I'll call this shooting.
And I'll set that equal to false.
But then when we're holding down our mouse and we have enough ammo, we're going to set shooting equal
to true.
And that means up here we can check if we're shooting our gun.
So if we're already shooting our gun, then we're just going to return.
And then we shoot our gun.
And then after our yield statement is up, we can go ahead and set shooting back to false to allow the
player to shoot the gun again.
Now, if our gun is automatic, we want to keep shooting our gun while our mouse button is held down
or until we run out of ammo.
So while our mouse button is being held down, what we want to do is we want to keep shooting the gun
and then we want to yield for that shot.
Cool down so we maintain that rate of fire.
And then after every single time we shoot, we want to check if the amount of ammo inside of our magazine.
Is less than or equal to zero.
And if it is, we're going to set mouse button down equal to false and then break out of this loop to
no longer shoot our gun anymore.
So we're going to be updating these attributes on the server.
Which is why inside of our shoot function we're going to have to fire an event to tell the server,
hey, we shot our gun, please subtract ammo from us and please detect what we've hit and apply damage
and stuff like that.
But this is how it should look when we press down our mouse button or we touch the screen, we're going
to shoot.
And while we are holding down our mouse button, if our gun is automatic, we're going to keep shooting
until our mouse button is released or we run out of ammo.
Now, the other useful thing with the shooting variable is we can go ahead and use it within the function
for reloading our gun, because we don't want to reload our gun in the middle of us shooting our gun.
So what we can do inside of the function for our reload is we want to check if the input state is equal
to the enum dot user input state, and we could do the end input state.
So once they release the R button on their keyboard, or they release from clicking on the button that's
on our screen, if they release, then what we want to do is we want to reload our gun, but we only
want to reload our gun when we're not shooting the gun.
So if we're shooting our gun still, then we're just going to return because we can't reload while we're
shooting the gun.
Now, when we unequip our gun, what we need to do is we need to stop shooting our gun.
So we got to set all of those booleans to false.
And then we want to unbind these different actions from our context action service because we're no
longer holding our gun.
So we want to set mouse button down equal to false.
We want to set shooting equal to false.
And then we want to unbind these actions.
So refer to the context action service.
Unbind the action which is our gun shoot.
And then we need to do the exact same thing for our gun reload.
We also want to reset the mouse icon back to the default.
And to do that we can refer to our mouse and set the icon to an empty string, which should set the
mouse icon back to the default.
Now we can go ahead and fill out our shoot and reload functions.
Now inside of our shoot function, what we need to do is we are going to raycast on the client side
and then send that raycast information to the server.
So we need to set up a raycast parameters to fill out certain types of instances in our game.
For example, we want to filter out our own character, and we also want to filter out the filtering
folder in our workspace.
So inside of the variable section I'm going to create a new raycast parameters.
So raycast params dot new.
And I'm going to set the params dot filter type equal to the enum dot raycast filter type dot exclude.
And then when we shoot our gun, we want to set Rams dot filter descendant instances equal to a table
that contains our player's character, as well as the workspace dot filtering folder.
And then we need to calculate the direction for our raycast.
So we'll call this our shot direction.
And that's going to be equal to our mouse's hit which is the keyframe of the mouse's position in 3D
space.
So we're converting wherever our mouse is on the screen to a position in the world.
So we'll get the hit, we'll get that position, and then we want to subtract it by the origin point,
which is going to be our gun dot handle.
And inside of each of the handles of our gun there is an attachment called muzzle.
And we want to get the world, see frame of that muzzle and then get its position.
And then we want to get a normalized vector or basically a vector that has a length of one stud.
So we're going to get the unit a normalized copy of the vector three one that has the same direction
as the original, but a magnitude of one.
This way we can customize how long we want this vector to be, depending on the properties for our gun.
After we get the shot direction, the next thing we need to determine is whether or not this is a shotgun
or a regular gun.
If this is a shotgun, then we want to spread the bullets out randomly.
But if it's a regular gun, then we only want to shoot one bullet in the shot direction that we've calculated.
So if our gun get attribute if the gun type is equal to the standard gun type.
Then what we can go ahead and do is raycast.
So we'll use the workspace and then the raycast function.
The origin is going to be our gun dot handle dot muzzle dot world keyframe.
Our position and then our direction is going to be our shot direction.
And then we want to multiply this by our properties dot max bullet distance.
So we get a ray that is 500 studs long and the direction that we've defined.
And then we can also pass our raycast parameters.
Then we can get a result from this raycast.
So if we have a result then we want to give this information to the server.
Otherwise if we don't have a result then we're just going to fire the event but not give any information
to the server.
So let's go ahead and make a reference to our gun event.
So that's going to be in replicated storage I'll just create a variable I'll call it gun event.
That's equal to replicated storage dot remotes dot gun event.
Now to create a standard of communication between the client and server.
Basically, what actions do we want the server to do when we click our gun or when we reload our gun?
We can create another module script inside of the enums folder and replicated storage.
And this is going to be our gun comms enum.
And then inside of here we can fill in the different actions that we want the server to do.
So I'm just going to copy this enum here.
Close that out and then paste it in here.
But inside of this table I want to have some actions specifically to give to our server.
One of those actions would be, for example, to validate one of our shots.
So when we shoot our gun, we want the server to check if we hit anything and apply any damage and stuff
like that.
So we could give an action of like a validate shot.
And then another action we want the server to validate is our reload.
So when the client reloads their gun we want to tell the server, hey, we're reloading.
Can you please put more ammo inside of my magazine.
So we'll call this validate reload.
Then we can go ahead and get this enum from upgraded storage.
So I'll just call this my gun comms enum and we'll require from replicated storage dot modules, dot
enums, dot gun comms enum.
And then we can go ahead and use those different constants to tell the server what kind of action we
want them to perform.
So when we have a result from our raycast, we're going to use our gun event and fire to the server.
Hey, we shot our gun!
Please validate our shot so we'll do gun comms enum dot two server dot validate shot, and then we want
to pass them a table containing all the information from our raycast.
Now unfortunately the raycast result that is returned from this function, we can't pass it through
a remote event.
The server will receive nil.
So we basically need to create our own custom table that stores all of the different results that we
want.
So I'm going to create a variable called remote compatible results.
And if we don't convert this raycast result into this table, then we're going to run into issues where
the server is not going to receive it.
This is just a limitation of remote events that we're going to have to work through.
But some of the information from this remote event that I'm going to want to give to the server is,
for example, what is the instance that we hit.
So that's going to be equal to my result dot instance.
Another example is we want to get the position of where we hit in the workspace.
So position is going to be equal to my result dot position.
And then we're also going to want to get the normal vector of the face we hit.
So it's called normal.
And it's going to be equal to my result dot normal.
And it says the normal vector of the intersected face.
So we're going to want that for the server as well.
So this is my remote compatible result.
And then inside of this table I'm going to be given to the server.
I can create a key and I'll just call it my raycast result.
And that's going to be equal to my remote compatible result table.
Now another thing I want to give to the server is the position of the instance on the client side,
because there's going to be a small delay between when we fire this remote event and the server retrieves
the information.
So I want to give the server information of where the instance position was on the client side.
And that way the server can check or compare the position of that instance on the server side to the
client side.
So I'll just call this the instance position.
And it's going to be equal to the result that instance.
And we're going to get the position of that instance.
And this is the information we're going to send to the server to validate our shot for later.
Now, if we didn't hit anything at all, then we can just simply use our gun event and fire to the server
to validate our shot.
So gun comms enum dot two server dot validate shot.
But we're not going to pass any more information because we didn't hit anything.
Instead, we just want the server to deduct one bullet from our magazine and stuff like that and play
the gunshot sound and make a muzzle flash, that kind of thing.
But if we did hit a result, then we want the server to verify that result.
And since we haven't set up the server script yet, I'm just going to print this result on the console.
And then the other thing we want to check is if our gun.
Get attribute gun type if it's equal to spread.
So if our gun is a shotgun then what we need to do is something a little bit different.
What we need to do is we need to create a whole bunch of different raycasts in different directions
to replicate the different pellets coming out of our shotgun.
So this means we're going to need a random data type here.
So random dot new.
And then we're going to create a table I'm going to call it all pellets.
And this table is going to store basically the same thing that we are sending to the server right here.
It's going to store the remote compatible result as well as the instance position.
But we're going to do that for every single pellet in our gun.
So you can imagine this as multiple different bullets in our gun stored in one table.
And then we're going to give this table to our server all at once.
And then the server can loop through all those different results and verify each one of them.
So what we want to do is we want to loop a set number of times.
So we're going to start our AI index at one.
And the number of times we need a loop is going to be equal to how many pellets is going to be coming
out of our gun.
So we're going to get the total pellets in our properties.
And again, this is going to be only for shotguns.
And then what we need to do is we need to randomize the direction of this pellet coming out of our shotgun.
So we want the direction to be somewhat similar to the shot direction of where our mouse is.
But we want to add a little bit of an angle difference.
So that way it spreads out like a shotgun would.
So to do that we're going to update our shot direction variable to be equal to.
And this is going to be a little bit complex.
But what we're going to do is we're going to create a new keyframe and we're going to use the lookup
function.
So we're going to get a position and then another position to look at.
So we'll get a keyframe from that.
The starting position is going to be our gun dot handle dot muzzle dot world keyframe.
That position.
So again, the same starting position and where we want to look is going to be equal to our mouse dot
hit dot position.
So this is basically just giving us the exact same vector as calculating it up here.
But instead we want to apply a little bit of a rotation by using a c frame dot angles.
Because after we apply that rotation, we can go ahead and get the look vector of the C frame, which
will be a vector that has a length or magnitude of one stud.
So it's going to be the exact same as this shot direction up here.
But instead we have a little bit of a random rotation to our vector.
So now what we want to do is we want to multiply this new C frame by a C frame angles.
Now let me get the look vector here.
And we want to rotate it randomly on the x and the y axis and not the z axis.
Because if you imagine this as like our 2D screen, we have an X and a y component to our screen, and
we need to rotate the ray randomly on the x and y axis to give that spread effect.
And the amount that we want to randomly rotate it by is defined in our properties.
So if we look at one of the properties for our shotgun, we had that max spread property.
And this is going to be in degrees of how severe the pellet spread is for our shotgun.
So what we need to do is for example, on the x axis we want to use math dot rad.
And then we want to get a random number between negative five and positive five.
So we could do RNG next integer.
Or actually we'll do next number.
And then it's going to be between our properties.
Max.
Spread.
And then we'll have a negative value to a positive value.
So we'll copy that and do that there as well.
And again we want to do this for both the x axis.
So let me copy this.
And then we also want to do it for the y axis.
And then for the z axis we do not care.
We're going to set that value equal to zero.
So now, to make this look a little bit more clear, I'm going to space this out there and space this
out there.
So we're getting a C frame that's looking at wherever our mouse is in the workspace from the muzzle
of our gun.
And then we're applying a slight rotation to that C frame on the x and y axis.
And then once we do all of that, we can go ahead and grab the look vector.
Which will give us a direction with a length or a magnitude of one stud that we can go ahead and then
multiply and by the max bullet distance.
So we're basically just randomizing a direction for each one of the pellets in our gun.
So after we have modified the shot direction then we can go ahead and do the exact same thing that we
did up here.
We'll raycast.
Multiply that shot direction by our bullet distance and then check if we got a result.
Now, if you remember inside of the properties module script for our shotgun, we only want to do this
randomization of the pellets.
If the round type is set to anything other than the slug round type.
So if I look in one of my shotguns, if you remember, we set one of the round types here to slug.
Since this is set to the slug round type, I don't want to randomize.
The pellets coming out of the shotgun, so we only want to randomize it.
If the round type is equal to slug.
So what we want to do in here is we want to check.
If the property's not around type is not equal to slug.
So if it's not equal to the slug round type, then we can go ahead and randomize the direction of our
pellet.
But otherwise we'll just keep the shot direction the same, like we've calculated up here.
And then actually let me move this into our for loop, because we need to do it for each one of the
pellets in our shotgun.
So we'll get the result for the first pellet and then the next pellet and then the next.
And when we grab that result, we want to check if we have a result from our raycast.
And if we do well we can go ahead and do is copy this right here and create another remote compatible
result.
And then instead of firing to the server for every single pellet, because that means we would be firing
our remote event many times instantaneously.
Instead, we're going to insert this result into our all pellets table.
So we'll use Table.insert, refer to all pellets and then we want to insert.
The same type of thing that we passed to the server right here.
So we'll copy this.
And the table or the value we're inserting into all palettes, is that right there?
So we're getting our remote compatible result, as well as the position of the instance that we hit
with this particular pellet.
And then once we're done looping through all of the total pellets in our gun.
Then we can go ahead and fire to the server.
So gun event, fire server.
The gun comms enum o2 server dot validate shot.
And we're just going to pass to the server the entirety of the all pellets table.
And then we'll just print out.
All of the pellets here on the client because again, we haven't set up the server script yet.
Okay, that was a lot of code to write, but we should be able to test what we have down so far and
see if we get any results printed out into the console.
If we hit something with one of our bullets, this should print the raycast result of what we hit.
If we didn't hit anything, then this should print nil inside of our assault rifle.
What we can go ahead and do is we'll just copy our assault rifle and paste that clone inside of our
starter pack.
And then we can go ahead and playtest the game to see if we get any raycast results from trying to shoot
our gun.
So we didn't get any errors in the console, which is always good.
And then here we're holding our gun.
We're going to be adding animations for our guns later.
But right now we need to just set up the basics for our gun.
So if I click my gun.
As you can see, we got a raycast result and it hit a union in our game at this position.
As you can see, we got the normal of the face we hit, and then it also tells us the material that
we hit as well.
So that is our raycast result.
If I shoot maybe this barrier right here.
As you can see, it tells us we hit a concrete barrier at this position.
Very cool.
Maybe if I walk over here and shoot this, um, let me shoot this door over here.
If I shoot that, it says we hit a part.
Maybe if I shoot this.
As you can see, it says we hit a sandbag barrier.
So it looks like our raycast on the client is working fine.
We're hitting the sidewalk or we're hitting this ground part.
Or maybe if we shoot this over here, we're hitting a trash pile.
Again, we're hitting more sandbags.
Very cool.
So it looks like our raycasts are correctly calculating what they are hitting.
So the next thing I want to go ahead and test to see what the output will be for a shotgun.
So I can go ahead and copy this local script.
And then let me just pick out a random shotgun like this one.
I'll just paste that local script inside of there, and then I'll copy this shotgun and then paste it
in my starter pack.
And then we can play test the game again.
We'll go and play the game, and then let's see what the result is going to be for every single pellet
that comes out of our shotgun.
So if I just shoot right here.
There we go.
We got a table printed out.
And this shotgun shoots out 16 different pellets.
So as you can see, we got the result for each one of the pellets that came out of our shotgun.
Here.
It tells us the position of the instance that we hit, and it tells us that we hit a part.
This one also hit a part.
Let's go ahead and look through all the different.
This one hit a part so it looks like they all just hit the part.
Let me shoot them at one of my barriers and actually let me back up a little bit.
So one of the pellets could have the chance to hit something in the background.
So if I shoot.
There we go.
We got another result and let's go ahead and see what they hit.
This one hit a part.
That one also hit a part.
That one hit a part.
That one hit a part part.
Let me see if any hit the concrete barrier.
That one hit a part.
So far, it looks like none of them hit the concrete barrier.
So looks like they're all still hitting some kind of part.
Maybe if I walk closer and I shoot my concrete barrier like that, maybe we'll get a different result.
There we go.
Since we hit the concrete barrier, if I back up and maybe have like half the pellets hit the barrier,
so I shoot.
There, I got a different result.
Let's see what the result for that is.
Okay, some of them hit the concrete barrier.
Hopefully some of them didn't.
So let's see if any hit a different part.
Concrete barrier.
Actually, it looks like the pellets are all hitting at the exact same position and they are not spreading
out correctly.
If you take a look at the different positions of where these pellets are hitting, they're all hitting
at the same position.
So it appears that the randomization of the direction of our pellets is not working correctly.
So we need to go ahead and troubleshoot why that is.
All right.
And the reason why the pellets were not randomizing or spreading out randomly is because we made a minor
mistake with our next number function call, and that's because we forgot to remove this negative symbol
for the x and then for the y position.
So it was picking the exact same number because it was constrained between the exact two same numbers.
So now that we got rid of those negative symbols, our pellets should be spreading out randomly.
So let me go ahead and copy this script and then update that and paste it inside of our semi-auto shotgun.
And let's go ahead to test to see if the pellets are now spreading out randomly.
So if I go and I shoot, let me put my crosshair halfway between my barrier.
About half of my pellets should have hit the barrier, and then the other half should have hit other
stuff behind in that direction.
So let's go ahead and take a look at the results.
So as you can see, there we go.
One of them hit my sidewalk, which was in the background.
Another one hit my concrete barrier.
And as you can see, the position of where they're hitting these elements are different.
This one also hit the concrete barrier.
This result hit the barrier.
What did this one hit?
This one hit a block somewhere at a different position.
This one hits the barrier as well.
This one hit another block.
This one hit the barrier.
That one also hit the sidewalk.
So as you can see, all of the pellets randomly spread out and hit different things.
That was either the barrier or stuff behind the barrier.
Very cool.
The last thing we can go ahead and fill out for this lecture is going to be the reload function.
So when we want to reload the gun first we want to verify that the amount of bullets in our magazine
is less than the max bullets that we can hold in our magazine, which signifies we need to reload.
So if our gun and we get the attribute ammo and magazine if that is equal to our properties dot max
mag ammo, then the player doesn't need to reload.
Or if the player doesn't have any reserve ammo left, then they can't reload either.
So if gun get attributes ammo reserve if that is equal to zero, then we're just going to return because
the player can't reload their gun.
We also need to create a Debounce for our reload function and we'll create another variable.
I'll call this reloading set that equal to false.
And that way while we are reloading our gun, we also can't shoot our gun.
So what we want to do in here is we want to set reloading equal to true.
And then if we are already reloading our gun we don't need to reload it again.
So we'll return there.
And then if we want to shoot our gun, what we want to check here is if we are shooting, we're going
to return.
And if we are reloading, then we also want to return.
And then what we can do is after we set reloading equal to true, we can go ahead and play the reloading
sound.
So we'll create another new sound.
And that's going to be create sound.
We'll pass gun dot handle and then we'll pass properties dot reload sound properties.
We'll play that sound, and then we'll wait for that sound to end.
So we'll connect a function to that.
And then we're going to go ahead and destroy that sound.
And then here is where we would play like our reload animation.
But since we don't have a reload animation at the moment as a placeholder, I'm just going to put a
yield statement here and we're going to wait for the properties dot reload duration.
And then afterwards we want to go ahead and fire to the server to reload our guns.
So gun coms enum dot two server dot validate reload.
Now we only want to reload our gun if we still have it equipped.
So if let's say the player reloads their gun, but then they unequip their gun in the middle of reloading
it.
We don't want to tell the server to reload our gun.
So what we can do is when we unequip our gun, we can also set reloading equal to false and then back
inside of our reload function we can check if we are reloading.
So if reloading is still true then we can go ahead and fire to the server to reload our gun.
And then once that is all done, we can go ahead and set reloading equal to false.
So now to test this out, we can just basically print that we're reloading.
And then we can go ahead and copy this local script and paste it into our two guns.
And then we can go ahead and get rid of the previous local scripts.
And then I'm going to set the ammo my guns to zero.
So that way we can actually test out to see if they're going to reload.
Of course the attributes aren't going to update, but at least we can still hear the reloading sound
as well as the gun clicks sound.
So since neither of my guns have ammo in the magazines, if I click, as you can see, it's pulling
that click sound that we're out of ammo.
And the same thing should happen with our shotgun.
So if I click, as you can see, we can't shoot because we have no ammo.
Now if I hit R there we go.
The reload sound is playing.
And as you can see inside of the console it has printed reloading.
Perfect.
We can do the same thing for the AR.
If I press R we're reloading the gun and then it should print reloading.
There we go.
Perfect.
Reloading.
So now we have all the client functionality set up for our guns.
The next thing we need to do is start scripting and filling out all the functionality for verifying
and validating when our gun shoots and when our gun reloads.
And then the server can handle all of that kind of stuff, like checking and applying damage, updating
the attributes in our gun, playing the muzzle flash and the gun shoot, sound effects and all that
kind of good stuff.
If you're ready to do all of that, then I will see you in the next lecture.